﻿// This Code is written by Tahir Çakmak, tahircakmak.blogspot.com 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;

namespace MainLibrary
{
internal class ProxyFactory<TObject> : RealProxy
{
    public TObject RealObject { get; private set; }

    public ProxyFactory(TObject realObject)
        : base(typeof(TObject))
    {
        this.RealObject = realObject;
    }


    private Func<Func<object>, object> _surroundDelegate;
    public TObject GetProxy(Func<Func<object>, object> surroundDelegate)
    {
        this._surroundDelegate = surroundDelegate;
        return (TObject)this.GetTransparentProxy();
    }

    public override IMessage Invoke(IMessage msg)
    {
        //Bu örnek gelen çağrımın bir metot olduğu varsayımı altında yapılmıştır.
        //Eğer çağrım bir Property ise ona göre bu kodu değiştirmek gerekir.Yani set_ ve get_ önekleri ile metodu dinamik bir şekilde çağırmak gerekir.

        IMethodCallMessage message = (IMethodCallMessage)msg;

        if (message != null)
        {
            //MessageBox.Show(message.MethodName + " metodu çağrılmak üzere. Biz araya girdik çağrılmadan önce");

            object methodRetval = _surroundDelegate(() => message.MethodBase.Invoke(RealObject, message.InArgs));

            ReturnMessage retVal = new ReturnMessage(methodRetval, null, 0, message.LogicalCallContext, message);

            return retVal;
        }
        return null;
    }
}

}

